iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0
自我挑戰組

利用 node.js/express 架設網站系列 第 16

Day-16 應用中間件與安全性最佳實踐

  • 分享至 

  • xImage
  •  

1.理解中間件的概念與作用
2.使用中間件管理請求與響應
3.學習應用安全性最佳實踐
4.應用安全驗證與授權

理解中間件的概念與作用

中間件(Middleware) 是在 Express 應用中處理請求和響應的函數。中間件可以在請求進入路由之前或響應返回客戶端之前執行操作。
每個中間件函數接收三個參數:

  • req:請求對象。
  • res:響應對象。
  • next:調用下一個中間件的函數。
    範例:
app.use((req, res, next) => {
    console.log('Request URL:', req.originalUrl);
    next(); // 繼續到下一個中間件或路由處理
});

Express 內建了幾個常用的中間件,例如解析 JSON 和 URL 編碼數據:

app.use(express.json()); // 解析 JSON 數據
app.use(express.urlencoded({ extended: true })); // 解析 URL 編碼數據

使用中間件管理請求與響應

  • 日誌中間件(morgan)
    morgan 是一個用於記錄 HTTP 請求的中間件,特別有助於開發過程中的調試和監控。
    安裝 morgan:
npm install morgan

使用 morgan:

const morgan = require('morgan');
app.use(morgan('dev')); // 記錄請求日誌
  • 安全相關的中間件(Helmet)
    helmet 是一個 Express 中間件,用於設置 HTTP 標頭來提升應用的安全性,能有效防範常見的 Web 攻擊。
    安裝 Helmet:
npm install helmet

使用 Helmet:

const helmet = require('helmet');
app.use(helmet()); // 自動設置多個安全相關的 HTTP 標頭

應用安全性最佳實踐

  • 使用 HTTPS 保護數據傳輸
    HTTPS(超文本傳輸安全協定)能夠加密客戶端與伺服器之間的通信,防止數據被竊聽或篡改。
    在本地開發環境中,可以使用自簽名證書測試 HTTPS。以下是使用 Node.js 和 HTTPS 的基本設置:
const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('path/to/key.pem'),
  cert: fs.readFileSync('path/to/cert.pem')
};

https.createServer(options, app).listen(443, () => {
    console.log('HTTPS Server running on port 443');
});
  • 使用 Helmet 提升安全性
    Helmet 能夠自動設置一些 HTTP 標頭來防止多種常見的 Web 攻擊,如:

    • XSS(跨站腳本攻擊):helmet.xssFilter() 設置 X-XSS-Protection 標頭來防止跨站腳本攻擊。
    • CSRF(跨站請求偽造):可以與 csurf 庫結合使用來防止 CSRF 攻擊。
    • Content Security Policy:設定嚴格的內容安全政策,防止外部資源載入惡意代碼。
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "trustedscripts.com"],
    objectSrc: ["'none'"],
    upgradeInsecureRequests: [],
  }
}));

應用安全驗證與授權

  • 使用 JWT 進行驗證
    JWT(JSON Web Token)是一種常用的驗證方式,適合保護 API 路由。客戶端在登錄後獲取 JWT,並在之後的請求中攜帶該令牌來進行身份驗證。
    安裝 jsonwebtoken:
npm install jsonwebtoken

生成 JWT:

const jwt = require('jsonwebtoken');

const token = jwt.sign({ userId: user._id }, 'your_secret_key', { expiresIn: '1h' });
res.json({ token });

驗證 JWT:

const jwt = require('jsonwebtoken');

const authenticateJWT = (req, res, next) => {
    const token = req.header('Authorization').replace('Bearer ', '');
    if (!token) {
        return res.status(401).json({ error: 'Access denied' });
    }
    try {
        const decoded = jwt.verify(token, 'your_secret_key');
        req.user = decoded;
        next();
    } catch (err) {
        res.status(400).json({ error: 'Invalid token' });
    }
};

app.use('/protected-route', authenticateJWT, (req, res) => {
    res.send('This is a protected route.');
});

上一篇
Day-15 部署 Node.js 和 Express 應用到伺服器
下一篇
Day-17 伺服器設定與環境準備
系列文
利用 node.js/express 架設網站26
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言